﻿// Created by amoylel on 06/13/2017.
// Copyright (c) 2017 amoylel All rights reserved.

#ifndef AMO_CONSTANTS_HPP__
#define AMO_CONSTANTS_HPP__

#include <string>

#include <amo/ipc/any.hpp>
#include <amo/ipc/ipc_args_pos_info.hpp>
#include <amo/ipc/ipc_constants.hpp>
#include <amo/ipc/any_args_list.hpp>

namespace amo {

    /*!
    * @class	ipc_message
    *
    * @brief	进程消息封装.
    */
    class ipc_message {
    public:
        typedef std::shared_ptr<ipc_message> SmartType;
    public:
        /*!
        * @fn	static int ipc_message::GetProcessMessageID()
        *
        * @brief	生成消息ID.
        *
        * @return	生成的ID.
        */
        static int getProcessMessageID() {
            static int id = 0;
            static std::mutex mutex;
            return ++id;
        }
        
    public:
        ipc_message() {
            m_nID = getProcessMessageID();
            
            m_pMessageList.reset(new any_args_list());
        }
        
        
        ~ipc_message() {
        }
        
        /*!
        * @fn	int ipc_message::getID() const
        *
        * @brief	获取消息ID.
        *
        * @return	消息ID.
        */
        int getID() const {
            return m_nID;
        }
        
        void setID(const int64_t& nID) {
            m_nID = nID;
        }
        
        /*!
        * @fn	static ipc_message ipc_message::fromJson(amo::u8json& json)
        *
        * @brief	将JSON转换为ipc_message.
        *
        * @param [in]	json	The JSON.
        *
        * @return	An ipc_message.
        */
        static ipc_message fromJson(const amo::u8json& json) {
            ipc_message message;
            message.m_strMessageName = json.get<std::string>("name");
            message.m_nID = json.get<int>("id");
            amo::u8json args = json.get<amo::u8json>("args");
            message.m_pMessageList = any_args_list::fromJson(args);
            return message;
        }
        
        static ipc_message::SmartType Empty() {
            return std::shared_ptr<ipc_message>(new ipc_message());
        }
        /*!
        * @fn	const std::string& ipc_message::getMessageName() const
        *
        * @brief	获取消息名称.
        *
        * @return	消息名称.
        */
        const std::string& getMessageName() const {
            return m_strMessageName;
        }
        
        /*!
        * @fn	const std::string& ipc_message::GetName() const
        *
        * @brief	获取消息名称.
        *
        * @return	消息名称.
        */
        const std::string& getName() const {
            return m_strMessageName;
        }
        
        /*!
        * @fn	void ipc_message::setMessageName(const std::string& name)
        *
        * @brief	设置消息名称.
        *
        * @param	name	消息名称.
        */
        void setMessageName(const std::string& name) {
            m_strMessageName = name;
        }
        
        /*!
        * @fn	std::shared_ptr<any_args_list>& ipc_message::GetArgumentList()
        *
        * @brief	获取参数列表.
        *
        * @return	std::shared_ptr<any_args_list>.
        */
        std::shared_ptr<any_args_list>& getArgumentList() {
            return m_pMessageList;
        }
        
        /*!
        * @fn	void ipc_message::SetArgumentList(std::shared_ptr<any_args_list> list)
        *
        * @brief	设置消息列表.
        *
        * @param	list	The list.
        */
        void setArgumentList(std::shared_ptr<any_args_list> list) {
            m_pMessageList = list;
        }
        
        amo::u8json toJson() const {
            amo::u8json json;
            json.put("name", m_strMessageName);
            json.put("id", m_nID);
            json.put_child("args", m_pMessageList->toJson());
            return json;
        }
        
        SmartType clone() {
            SmartType msg(new ipc_message());
            msg->setMessageName(m_strMessageName);
            msg->setArgumentList(m_pMessageList->clone());
            msg->setID(getID()); // 考虑这个要不要复制
            return msg;
        }
    private:
        /*! @brief	消息名. */
        std::string m_strMessageName;
        /*! @brief	参数列表. */
        std::shared_ptr<any_args_list> m_pMessageList;
        /*! @brief	消息ID. */
        int m_nID;
    };
    
    template<> struct any_value_type < ipc_message > {
        static const char value = 31;
    };
    
    template<>   ipc_message string_to_any(const std::string& val) {
        return ipc_message::fromJson(amo::u8json(val));
    }
    
    template<>   std::string any_to_string<ipc_message>(const ipc_message& val) {
        return val.toJson().to_string();
    }
}
#endif // AMO_CONSTANTS_HPP__